/* Include these
   #include <pthread.h>
   #include <rid.h>
   #include <stdint.h>

   #include <nit/list.h>
   #include <nit/set.h>
   #include <nit/map.h>
 */

typedef struct Oas_mail Oas_mail;

struct Oas_mail {
	Oas_mail *next;
	Rid sender;
	void *msg;
};

typedef struct Oas_sys Oas_sys;

typedef int (*Oas_begin)(Rid self, void *local, Oas_sys *sys);

typedef int (*Oas_act)(Rid self, const Rid sender, void *msg, void *local,
		       Oas_sys *sys);

typedef void (*Oas_die)(Rid self, Oas_mail *mail, void *local, Oas_sys *sys);

typedef int (*Oas_lost)(const Rid sender, void *msg, Oas_sys *sys);

typedef struct Oas_actor Oas_actor;

struct Oas_sys {
	Nit_map actors;
	Nit_entry *entries;
	pthread_rwlock_t actors_lock;

	Oas_actor *olds;
	pthread_mutex_t olds_mutex;

	Oas_mail *mails;
	pthread_mutex_t mails_mutex;

	int last_set;
	pthread_t last_thread;
	pthread_cond_t done_cond;
	pthread_mutex_t done_mutex;

	void *global;
	Oas_lost lost;
};

int
oas_init(Oas_sys *sys, void *global, Oas_lost lost);

int
oas_add(Oas_sys *sys, const Rid id, Oas_mail *mail, void *local,
	Oas_begin begin, Oas_act act, Oas_die die);

int
oas_msg(Oas_sys *sys, const Rid sender, const Rid to, void *msg);

void
oas_wait(Oas_sys *sys);

void *
oas_dispose(Oas_sys *sys);
